package dovs.instructions;

/**
 * A method or constructor signature. Used to encapsulate method or constructor
 * signature parameters to instructions.
 */
public class MethodSignature {
	private String sig;

	private int nargs;

	private int nreturns;

	/**
	 * Create a method or constructor signature. Calculate the number of
	 * parameters and return values from the signature.
	 * 
	 * @param sig
	 *            the signature of the method or constructor as returned by
	 *            <code>AMethodDecl.getSignature()</code> or
	 *            <code>AConstructorDecl.getSignature()</code>.
	 */
	public MethodSignature(String sig) {
		this.sig = sig;

		nargs = 0;
		// Parse signature
		int i;
		for (i = sig.indexOf('(') + 1; sig.charAt(i) != ')'; i++) {
			switch (sig.charAt(i)) {
			case 'L':
				while (sig.charAt(++i) != ';') {
					;
				}
				nargs++;
				break;
			case '[':
				break;
			default:
				nargs++;
			}
		}
		switch (sig.charAt(i + 1)) {
		case 'V':
			nreturns = 0;
			break;
		default:
			nreturns = 1;
		}
	}

	public String getSignature() {
		return sig;
	}

	@Override
	public String toString() {
		return getSignature();
	}

	/**
	 * The number of arguments the method takes.
	 * 
	 * @return the number of parameters
	 */
	public int numberOfArguments() {
		return nargs;
	}

	/**
	 * The number of values the method returns.
	 * 
	 * @return 0 for void, 1 for any other type
	 */
	public int numberOfReturns() {
		return nreturns;
	}

	@Override
	public boolean equals(Object o) {
		return sig.equals(((MethodSignature) o).sig);
	}

	@Override
	public int hashCode() {
		return sig.hashCode();
	}
}
